﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnitTests.Framework;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTests.FrameworkTests
{
	/// <summary>
	/// Test class for a Pop3 Client Handler
	/// </summary>
	internal class Pop3TestClient : TestClientBase<Pop3ClientHandler>
	{
		/// <summary>
		/// Default constructor
		/// </summary>
		/// <param name="port">Tcp port to use</param>
		public Pop3TestClient(int port = 11000) : base(port)
		{}

		public string ServerTimestamp { get; private set; }

		/// <summary>
		/// Sends a command to the server and verifies its response
		/// </summary>
		/// <param name="command">Command to send to the server (without \r\n)</param>
		/// <param name="message">Message to print if any assert fails</param>
		/// <param name="expectSuccess">Is the command expected to succeed</param>
		/// <param name="expectedResponseLines">If null then the response is expected to be a single line, otherwise this indicates the number of lines expected in the response (excluding the termination octect's line)</param>
		public void ProcessCommand(string command, string message = null, bool expectSuccess = true, int? expectedResponseLines = null)
		{
			// Generate default message
			message = message ?? string.Format("Incorrect response to {0}", command);
			
			// Get response from server
			string response = null;
			if (expectedResponseLines.HasValue)
				response = WriteLineReadUntil(command, '.');
			else
				response = WriteReadLine(command);

			// Check response
			if (expectSuccess)
				Assert.IsTrue(IsSuccess(response), message);
			else
				Assert.IsTrue(IsError(response), message);

			// If multiline, check response length
			if (expectedResponseLines.HasValue)
				Assert.AreEqual<int>(response.Count(x => x == '\n'), expectedResponseLines.Value, message);
		}

		protected override bool VerifyWelcomeMessage(string message)
		{
			ServerTimestamp = null;
			if (message.EndsWith(">"))
			{
				int beginTriagleIndex = message.LastIndexOf('<');
				if (beginTriagleIndex >= 0)
				{
					ServerTimestamp = message.Substring(beginTriagleIndex, message.Length - beginTriagleIndex);
				}
			}

			return IsSuccess(message);
		}

		private bool IsError(string response)
		{
			return response.StartsWith(Pop3ClientHandler.ERROR_PREFIX);
		}

		private bool IsSuccess(string response)
		{
			return response.StartsWith(Pop3ClientHandler.SUCCESS_PREFIX);
		}
	}
}
